﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using XRM.Security.DataAccess;
using XRM.Security.DataAccess.Enums;
using XRM.Security.DataAccess.Helpers;
using XRM.Security.WebUI.Controllers;
using XRM.Security.WebUI.Helpers;
using db = XRM.Security.DataAccess.Models;

namespace XRM.Security.WebUI.Models.UserRegister
{
    public class UserRegisterListModel : BaseViewModel
    {
        public UserRegisterListModel()
        {
            UserList = new List<UserRegisterModel>();
        }

        [Display(Name = "Поиск")]
        public string TextFilter { get; set; }
        [Display(Name = "Искать среди уволенных/в длительном отпуске")]
        public bool ShowAllFilter { get; set; }
        
        public List<UserRegisterModel> UserList { get; set; }
    }

    public class UserRegisterModel : BaseViewModel, IValidatableObject
    {
        public UserRegisterModel()
        {
            Status = UserStatus.Work; 
            PCList = new List<PCModel>();
            InfoSystemList = new List<UserInfoSystemModel>();
        }

        public UserRegisterModel(db.UserRegister dbEntity)
        {
            PCList = new List<PCModel>();
            InfoSystemList = new List<UserInfoSystemModel>();

            Id = dbEntity.UserRegisterId;

            FirstName = dbEntity.FirstName;
            LastName = dbEntity.LastName;
            MotherName = dbEntity.MotherName;
            FullName = dbEntity.FullName();
            Post = dbEntity.Post;
            Account = dbEntity.Account;
            
            if ( dbEntity.DepartmentId.HasValue )
            {
                DepartmentId = dbEntity.DepartmentId;
                DepartmentName = dbEntity.Department.Name;
            }

            if ( dbEntity.DepartmentAddressId.HasValue )
            {
                DepartmentAddressId = dbEntity.DepartmentAddressId;
                DepartmentAddressName = dbEntity.DepartmentAddress.Address;
            }

            if (dbEntity.PCs != null && dbEntity.PCs.Any())
            {
                foreach (db.UserPC item in dbEntity.PCs)
                {
                    PCList.Add(new PCModel(item.PC));
                }
            }

            if (dbEntity.InfoSystems != null && dbEntity.InfoSystems.Any())
            {
                foreach (db.UserInfoSystem item in dbEntity.InfoSystems)
                {
                    InfoSystemList.Add(new UserInfoSystemModel(item));
                }
            }

            Status = (UserStatus)dbEntity.Status;
            IsADUser = dbEntity.IsADUser;
        }

        public void ApplyChanges(db.UserRegister userRegister)
        {
            userRegister.LastName = LastName;
            userRegister.FirstName = FirstName;
            userRegister.MotherName = MotherName;
            userRegister.Post = Post;
            userRegister.Account = Account;
            userRegister.DepartmentId = DepartmentId;
            userRegister.DepartmentAddressId = DepartmentAddressId;
            userRegister.Status = (int)Status;
        }

        public override void Init(IDataManager dataManager)
        {
            DepartmentAllList = dataManager.DepartmentRepository.GetAll(x => x.IsDeleted == false).ToSelectedList().AddFirst( SelectedListHelper.EmptyDepartmentItem );
            DepartmentAddressAllList = GetDepartmentAddressList( dataManager, DepartmentId );
        }

        public static List<SelectListItem> GetDepartmentAddressList(IDataManager dataManager, int? departmentId)
        {
            var list = new List<SelectListItem> { SelectedListHelper.EmptyDepartmentAddressItem };
            if ( departmentId.HasValue )
            {
                list.AddRange( dataManager.DepartmentAddressRepository.GetByDepartmentId( departmentId.Value ).ToSelectedList() );
            }
            return list;
        }

        [Display(Name = "Имя")]
        [Required(ErrorMessage = "Поле 'Имя' обязательное")]
        [MaxLength(50, ErrorMessage = "Максимальная длина поля 'Имя' 50 символов")]
        public string FirstName { get; set; }

        [Display(Name = "Фамилия")]
        [Required(ErrorMessage = "Поле 'Фамилия' обязательное")]
        [MaxLength(50, ErrorMessage = "Максимальная длина поля 'Фамилия' 50 символов")]
        public string LastName { get; set; }

        [Display(Name = "Отчество")]
        [MaxLength(50, ErrorMessage = "Максимальная длина поля 'Отчество' 50 символов")]
        public string MotherName { get; set; }

        public string FullName
        {
            get; private set;
        }

        [Display(Name = "Должность")]
        [MaxLength(500, ErrorMessage = "Максимальная длина поля 'Должность' 500 символов")]
        public string Post { get; set; }

        [Display(Name = "Подразделение")]
        public int? DepartmentId { get; set; }
        public string DepartmentName { get; set; }

        [Display(Name = "Адрес")]
        public int? DepartmentAddressId { get; set; }
        public string DepartmentAddressName { get; set; }

        public bool IsADUser { get; set; }
        public string IsADUserCaption
        {
            get
            {
                return IsADUser?"да":"нет";
            }
        }
        
        [Display(Name = "Учетная запись")]
        [MaxLength(100, ErrorMessage = "Максимальная длина поля 'Учетная запись' 100 символов")]
        public string Account { get; set; }

        [Display(Name = "Статус")]
        public UserStatus Status { get; set; }
        public string StatusCaption
        {
            get
            {
                return Status.Description();
            }
        }

        public List<ListItem> StatusList
        {
            get
            {
                List<ListItem> result = new List<ListItem>();
                foreach (UserStatus item in (UserStatus[])Enum.GetValues(typeof(UserStatus)))
                {
                    result.Add(new ListItem { Text = item.Description(), Value = ((int)item).ToString() });
                }
                return result;
            }
        }
        
        public List<PCModel> PCList { get; set; }
        public List<PCModel> PCAllList { get; set; }
        
        public List<UserInfoSystemModel> InfoSystemList { get; set; }
        public List<SelectListItem> DepartmentAllList { get; set; }
        public List<SelectListItem> DepartmentAddressAllList { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (DepartmentId.HasValue)
            {
                var department = Controller.DepartmentRepository.Get( DepartmentId );
                if (department == null)
                {
                    yield return new ValidationResult( "Подразделение не найдено", new[] { "DepartmentId" } );
                    yield break;
                }
                if (DepartmentAddressId == null)
                {
                    yield return new ValidationResult( "Не указан адрес подразделения", new[] { "DepartmentAddressId" } );
                }
                else if (department.DepartmentAddresses.All(s => s.DepartmentAddressId != DepartmentAddressId))
                {
                    yield return new ValidationResult( "Адрес подразделения не найден", new[] { "DepartmentAddressId" } );
                }
            }
            if (!IsEdit && Controller.UserRegisterRepository.GetAll(x => x.LastName == LastName && x.FirstName == FirstName &&
                x.MotherName == MotherName).Any())
            {
                yield return new ValidationResult( "Пользователь с указанными ФИО уже существует в системе", new[] { "FullName" } );
            }
            if (IsEdit && Controller.UserRegisterRepository.GetAll(x => x.LastName == LastName && x.FirstName == FirstName &&
                x.MotherName == MotherName && x.UserRegisterId != Id.Value).Any())
            {
                yield return new ValidationResult("Пользователь с указанными ФИО уже существует в системе", new[] { "MotherName" });
            }
        }
    }
}